import requests
import json
import os
from dotenv import load_dotenv

load_dotenv()
from langchain.tools import BaseTool
from langchain.tools import tool
from typing import List, Tuple

appid = os.getenv('WX_APP_ID')
appsecret = os.getenv('WX_APP_SECRET')

# 获取access_token
def get_access_token(appid, appsecret):
    """
    使用appid和appsecret获取access_token。

    参数:
        appid (str): 微信公众号的appid。
        appsecret (str): 微信公众号的appsecret。

    返回:
        str: 获取到的access_token。
    """
    url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={appsecret}'
    response = requests.get(url)
    data = response.json()
    if 'access_token' in data:
        return data['access_token']
    else:
        print('获取access_token失败：', data)
        return None

access_token = get_access_token(appid, appsecret)

# 获取文章列表
def get_article_list(access_token):
    """
    使用access_token获取文章列表。

    参数:
        access_token (str): 用于验证的access_token。

    返回:
        list: 获取到的文章列表。
    """
    url = f'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={access_token}'
    data = {
        "type": "news",
        "offset": 0,
        "count": 10
    }
    response = requests.post(url, json=data)
    data = response.json()
    if 'errcode' not in data:
        return data['item']
    else:
        print('获取文章列表失败：', data)
        return None

def decode_iso(string):
    """
    将ISO-8859-1编码的字符串转换为UTF-8。

    参数:
        string (str): ISO-8859-1编码的字符串。

    返回:
        str: 转换为UTF-8编码的字符串。
    """
    return string.encode('iso-8859-1').decode('utf8')

# articles = get_article_list(access_token)
# if articles:
#     # 打印article下有那些key
#     print(articles[0]["content"]['news_item'][0]['title'])

#     for article in articles:
#         print('标题：', decode_iso(article['content']['news_item'][0]['title']))
#         print('链接：', decode_iso(article['content']['news_item'][0]['url']))
#         print('摘要：', decode_iso(article['content']['news_item'][0]['digest']))
#         print('\n')


class MpTool(BaseTool):
    name = 'mp_tool'
    description = '从微信公众号获取文章列表'

    def _run(self, input) -> list:
        """
        从我的微信公众号获取文章列表，并返回格式化的文章信息列表。

        返回:
            list: 包含每篇文章的标题，URL和摘要的字典列表。
        """
        # Do something with the input text
        articles = get_article_list(access_token)
        article_list = []
        if articles:
            for article in articles:
                article_list.append({
                    'title': decode_iso(article['content']['news_item'][0]['title']),
                    'url': decode_iso(article['content']['news_item'][0]['url']),
                    'digest': decode_iso(article['content']['news_item'][0]['digest'])
                })
        return article_list


from langchain_openai import ChatOpenAI
from langchain.output_parsers import JsonOutputToolsParser,JsonOutputKeyToolsParser
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
from langchain.agents.format_scratchpad import format_to_openai_function_messages
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import AIMessage, HumanMessage
from langchain.agents import AgentExecutor
from langchain.agents import initialize_agent
from langchain.chains import VectorDBQA
from langchain.agents import AgentType

tools = [MpTool()]
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm_with_tools = llm.bind(functions=[convert_to_openai_function(t) for t in tools])
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一个公众号管理者，你的用户想要获取你的公众号的文章列表。"
        ),
        MessagesPlaceholder(variable_name="chat_history"),
        ("user", "{input}"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ]
)
def _format_chat_history(chat_history: List[Tuple[str, str]]):
    buffer = []
    for human, ai in chat_history:
        buffer.append(HumanMessage(content=human))
        buffer.append(AIMessage(content=ai))
    return buffer

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
result = agent.invoke(f"我的公众号文章中有没有关于工作周报汇报的文章？")
print(result)
# agent = (
#     {
#         "input": lambda x: x["input"],
#         "chat_history": lambda x: _format_chat_history(x["chat_history"])
#         if x.get("chat_history")
#         else [],
#         "agent_scratchpad": lambda x: format_to_openai_function_messages(
#             x["intermediate_steps"]
#         ),
#     }
#     | prompt
#     | llm_with_tools
#     | OpenAIFunctionsAgentOutputParser()
# )

# agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# agent_executor.invoke({"input": "我的公众号文章中有没有关于工作周报汇报的文章？"})
